package redis;

import org.junit.Test;
import redis.clients.jedis.*;

import java.util.*;

/**
 * Created by Duke on 2016/12/6.
 */

public class redis {


    static Jedis jedis = new Jedis("10.201.3.18", 6379);
    static Map<String, String> map = new HashMap<String, String>();

    static {
        jedis.auth("kntest%pw_@dk2");
        System.out.println("Connection to server sucessfully");
        System.out.println("Server is running: " + jedis.ping());

        map.put("name", "xinxin");
        map.put("age", "22");
        map.put("qq", "123456");
    }


    public static Optional get(String key) {
        // TODO: 2017/4/28 Return the type of the value stored at key in form of a string. 
        String type = jedis.type(key);
        switch (Type.valueOf(type)) {
            case hash:
                return Optional.ofNullable(jedis.hgetAll(key));
            case list:
                return Optional.ofNullable(jedis.lrange(key, 0, -1));
            case set:
                return Optional.ofNullable(jedis.smembers(key));
            case string:
                return Optional.ofNullable(jedis.get(key));
            case zset:
                return Optional.ofNullable(jedis.zrevrange(key, 0, -1));
            case none:
                return Optional.ofNullable("无此key");
            default:
                return Optional.ofNullable("new type");
        }

    }


//    private enum Type {
//        hash, set, string,list,none,zset;
//    }

    @Test
    public void hash2() {
        Map<String, String> map = new HashMap<>();
        map.put("1", "1");
        map.put("2", "2");
        jedis.hmset("test", map);
        jedis.expire("test", 300);
    }


    @Test
    public void hash6() {
        String key = "test1::list:v5";
        for (int i = 0; i < 20; i++) {
            for (int j = 0; j < 20; j++) {
                for (int k = 0; k < 20; k++) {
                    for (int p = 0; p < 20; p++) {
                        jedis.lpush(key, ":" + i + ":" + j + ":" + k + ":" + p + ":");
                        jedis.expire(key, 300);
                    }
                }
            }
        }
    }


    @Test
    public void hash5() {
        String key = "test:product:list:v5";
        for (int i = 0; i < 20; i++) {
            for (int j = 0; j < 20; j++) {
                for (int k = 0; k < 20; k++) {
                    for (int p = 0; p < 20; p++) {
                        jedis.sadd(key, ":" + i + ":" + j + ":" + k + ":" + p + ":");
                        jedis.expire(key, 300);
                    }
                }
            }
        }
    }

    /*todo redis scan*/
    @Test
    public void hash3() {
        String key = "suishoujiedian:product:list:v5";
        for (int i = 0; i < 20; i++) {
            for (int j = 0; j < 20; j++) {
                for (int k = 0; k < 20; k++) {
                    for (int p = 0; p < 20; p++) {
                        for (int q = 0; q < 20; q++) {
                            String k2 = ":" + i + ":" + j + ":" + k + ":" + p + ":" + q;
                            jedis.setex(key + k2, 300, k2);
                            jedis.sadd(key + k2, k2);
                        }
                    }
                }
            }
        }
    }

    @Test
    public void hash4() {
        String key = "suishoujiedian:product:list:v5*";
        String cursor = ScanParams.SCAN_POINTER_START;
        ScanParams scanParams = new ScanParams().match(key);
        do {
            ScanResult<String> scanResult = jedis.scan(cursor, scanParams);
            cursor = scanResult.getStringCursor();
            List<String> list = scanResult.getResult();
            // TODO: 2018/4/18
        } while (!"0".equals(cursor));

    }

    @Test
    public void hash() {
        jedis.hset("user1", "tel", "1212");
        /*查看哈希表 key 中，指定的字段是否存在*/
        System.out.println(jedis.hexists("user1", "name"));
        /*获取存储在哈希表中指定字段的值*/
        System.out.println(jedis.hget("user1", "name"));
        /*获取在哈希表中指定 key 的所有字段和值*/
        System.out.println(jedis.hgetAll("user1"));
        /*为哈希表 key 中的指定字段的整数值加上增量 increment */
        System.out.println(jedis.hincrBy("user1", "age", 1));
        /*获取所有哈希表中的字段*/
        System.out.println(jedis.hkeys("user1"));
        /*获取哈希表中字段的数量*/
        System.out.println(jedis.hlen("user1"));
        /*获取所有给定字段的值*/
        System.out.println(jedis.hmget("user1", "name", "tel"));
        System.out.println(jedis.hmset("user1", map));
        /*将哈希表 key 中的字段 field 的值设为 value:If the field already exists, and the HSET just produced an update of the value, 0 is
         *         returned, otherwise if a new field is created 1 is returned.*/
        System.out.println(jedis.hset("user1", "name", "shia"));
        /*只有在字段 field 不存在时，设置哈希表字段的值。If the field already exists, 0 is returned, otherwise if a new field is created 1 is returned.*/
        System.out.println(jedis.hsetnx("user1", "name", "shia"));
        /*获取哈希表中所有值*/
        System.out.println(jedis.hvals("user1"));
//        System.out.println(jedis.hscan("user1","*"));
    }

    @Test
    public void string() {

        System.out.println(jedis.set("string", "test"));
        System.out.println(jedis.get("string"));
        /*返回 key 中字符串值的子字符*/
        System.out.println(jedis.getrange("string", 0, 3));
        /*将给定 key 的值设为 value ，并返回 key 的旧值(old value)。*/
        System.out.println(jedis.getSet("string", "newTest"));
        /*对 key 所储存的字符串值，获取指定偏移量上的位(bit)。*/
        System.out.println(jedis.getbit("string", 16) + "121");
        /*获取所有(一个或多个)给定 key 的值。*/
        System.out.println(jedis.mget("string", "name"));
        /*对 key 所储存的字符串值，设置或清除指定偏移量上的位(bit)*/
        System.out.println(jedis.setbit("string", 15, false) + "121");
        System.out.println(jedis.getSet("string", "newTest"));

        /*将值 value 关联到 key ，并将 key 的过期时间设为 seconds (以秒为单位)。*/
        System.out.println(jedis.setex("newString", 2, "newTest1"));
        System.out.println(jedis.get("newString"));
        /*......*/
    }


    @Test
    public void t() {
        Set s = jedis.keys("*");
        Iterator it = s.iterator();
        while (it.hasNext()) {
            String key = (String) it.next();
            System.out.println(get(key).orElse(""));
        }
    }

    @Test
    public void testDel() throws InterruptedException {
        String key = "testDel";
        String str0 = "当主数据库遇到异常中断服务后。当主数据库遇到异常中断服务后当主数据库遇到异常中断服务后当主数据库遇到异常中断服务后当主数据库遇到异常中断服务后";
        String str = str0;
        for (int t = 0; t < 100; t++) {
            str += str;
            long exe = 0;
            int it = 0;
            for (int i = 0; i < 100; i++) {
                try {
                    long exe0 = 0;
                    jedis.set(key, str);
                    long cur = System.currentTimeMillis();
                    Long ret = jedis.del(key);
                    exe0 = (System.currentTimeMillis() - cur);
//                    System.out.println(" " + ret + "   :   " + exe0 + "   :    " + str.length());
                    Thread.sleep(5L);
                    exe += exe0;
                    it++;
                } catch (Exception ignore) {
                    Exception e = ignore;
                }
            }
            System.out.println(t + ":" + it + "-- 平均时间：" + (exe * 1.0) / it + "--，字符串长度：" + str.length());
        }
    }

    /**********************************************************************************************/
    /*连接池*/
    private static JedisPool pool = null;

    /**
     * 构建redis连接池
     *
     * @param ip
     * @param port
     * @return JedisPool
     */
    @Test
    public void tt() {
        getPool();
    }

    public static JedisPool getPool() {
        if (pool == null) {
            JedisPoolConfig config = new JedisPoolConfig();
            //控制一个pool可分配多少个jedis实例，通过pool.getResource()来获取；
            //如果赋值为-1，则表示不限制；如果pool已经分配了maxActive个jedis实例，则此时pool的状态为exhausted(耗尽)。
            config.setMaxTotal(500);
            //控制一个pool最多有多少个状态为idle(空闲的)的jedis实例。
            config.setMaxIdle(5);
            //表示当borrow(引入)一个jedis实例时，最大的等待时间，如果超过等待时间，则直接抛出JedisConnectionException；
            config.setMaxWaitMillis(1000 * 100);
            //在borrow一个jedis实例时，是否提前进行validate操作；如果为true，则得到的jedis实例均是可用的；
            config.setTestOnBorrow(true);
            pool = new JedisPool(config, "192.168.200.131", 6379, 10, "dycong");
        }
        return pool;
    }

    /**
     * 返还到连接池
     *
     * @param pool
     * @param redis
     */
    public static void returnResource(JedisPool pool, Jedis redis) {
        if (redis != null) {
            pool.returnResourceObject(redis);
        }
    }

    /**
     * 获取数据
     *
     * @param key
     * @return
     */
    public static String getr(String key) {
        String value = null;

        JedisPool pool = null;
        Jedis jedis = null;
        try {
            pool = getPool();
            jedis = pool.getResource();
            value = jedis.get(key);
        } catch (Exception e) {
            //释放redis对象
            pool.returnBrokenResource(jedis);
            e.printStackTrace();
        } finally {
            //返还到连接池
            returnResource(pool, jedis);
        }

        return value;
    }


}
